package com.sq.partner.manager.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.springframework.stereotype.Service;

import com.sq.partner.manager.common.Config;
import com.sq.partner.manager.dao.CardInfoDao;
import com.sq.partner.manager.dao.CommamtFeeDao;
import com.sq.partner.manager.dao.FacadeNewPaymentDao;
import com.sq.partner.manager.dao.OutboundCardApplyDao;
import com.sq.partner.manager.mybatis.model.CommamtFee;
import com.sq.partner.manager.mybatis.model.FacadeNewPayment;
import com.sq.partner.manager.mybatis.model.GatewayUser;
import com.sq.partner.manager.service.OutboundNewPayService;
import com.sq.partner.manager.util.DateUtil;
import com.sq.partner.manager.util.DecimalUtil;
import com.sq.partner.manager.util.FreeMarkerUtil;
import com.sq.partner.manager.util.HttpConnectorNewpayUtil;
import com.sq.partner.manager.util.LogUtil;

/**
 * 激活卡出库缴费（集中收款平台缴费）实现类service
 * 
 * @author zhouxx 2019-03-08
 *
 */
@Service
public class OutboundNewPayServiceImpl implements OutboundNewPayService {

    private static Logger logger = LogUtil
            .getLog(OutboundNewPayServiceImpl.class);

    @Resource
    FacadeNewPaymentDao facadeNewPaymentDao;
    @Resource
    private CommamtFeeDao commamtFeeDao;
    @Resource
    FacadeNewPaymentDao newPaymentDao;
    @Resource
    private OutboundCardApplyDao outboundCardApplyDao;
    @Resource
    private CardInfoDao cardInfoDao;

    /**
     * 取得出库信息
     * 
     * @param commamtId
     * @return
     * @throws Exception
     */
    @Override
    public CommamtFee queryForPay(String commamtId) throws Exception {
        return commamtFeeDao.queryForPay(commamtId);
    }

    /**
     * 根据条件查询payment信息
     * 
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public FacadeNewPayment queryNewPayment(HashMap<String, String> map)
            throws Exception {
        return newPaymentDao.queryNewPayment(map);
    }

    /**
     * 出库支付支付前保存支付信息
     * 
     * @param tp
     * @param userCode
     * @return
     * @throws Exception
     */
    @Override
    public FacadeNewPayment saveFacadeNewPayment(CommamtFee commamtFee,
            GatewayUser gatewayuser) throws Exception {
        String commamtId = commamtFee.getCommamtId();
        //Date disableDate = cardInfoDao.getMinDisableDate(commamtId);
        FacadeNewPayment newpayment = new FacadeNewPayment();
        Date date = new Date();
        newpayment.setChannelCode("jhcard");
        newpayment.setPayId(commamtId);
        newpayment.setTransTime(date);
        newpayment.setRdSeq(generatePaySerialNumber(commamtId));
        newpayment.setPaymentCode("jhcard" + commamtId);
        newpayment.setApplyEntity(gatewayuser.getUserComcode());
        newpayment.setAmount(DecimalUtil.round(commamtFee.getTotPremAMt(), 2));
        newpayment.setTitle("outboundCard");
        //newpayment.setExpireDate(disableDate);
        newpayment.setExpireDate(DateUtil.addDaysToDate(new Date(), 7));
        newpayment.setInsertDate(date);
        newpayment.setTransState("1");
        newpayment.setIsJhcard("1");
        facadeNewPaymentDao.saveFacadeNewPayment(newpayment);
        return newpayment;
    }

    /**
     * 出库用收款状态查询接口
     * 
     * @param facadeNewPayment
     * @return
     * @throws Exception
     */
    @Override
    public FacadeNewPayment noPaymentStatusForOut(
            FacadeNewPayment facadeNewPayment) throws Exception {
        facadeNewPayment.setTransState("4");// 查询前将支付状态改为处理中
        facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);
        // 调用收款状态查询接口
        long time1 = System.currentTimeMillis();
        Map<String, String> map = new HashMap<String, String>();
        map.put("RdSeq", facadeNewPayment.getRdSeq());
        Date date = new Date();
        map.put("TransDate", DateUtil.format(date, "yyyyMMdd"));
        map.put("TransTime", DateUtil.format(date, "HHmmss"));
        map.put("TransSeq", DateUtil.format(date, "yyyyMMddHHmmsss"));
        map.put("S3Sign", "");
        String templates = Config.getProp("pay.QryRecState.templates");
        String requestXml = FreeMarkerUtil.process(templates, map);
        try {
            logger.info("收款状态查询报文：" + requestXml);
            String url = Config.getProp("card.newpay.qryRecState.url");
            String responseXml = "";
            responseXml = HttpConnectorNewpayUtil.interaction(url, requestXml);

            logger.info("请求收款状态查询完成执行时间:"
                    + (System.currentTimeMillis() - time1));
            logger.info("查询收款状态返回报文：" + responseXml);
            Document document = DocumentHelper.parseText(responseXml);
            Element root = document.getRootElement();
            String RtnCode = selectSingleNodeByRoot(root, "/ATS/PUB/RtnCode");
            // 如果查询成功
            if ("success".equals(RtnCode)) {
                String transState = selectSingleNodeByRoot(root,
                        "/ATS/OUT/TransState");
                // 如果返回2-已收款，更新支付表信息
                if ("2".equals(transState)) {
                    String rdSeq = selectSingleNodeByRoot(root,
                            "/ATS/OUT/RdSeq");
                    String cancelState = selectSingleNodeByRoot(root,
                            "/ATS/OUT/CancelState");
                    String corpAct = selectSingleNodeByRoot(root,
                            "/ATS/OUT/CorpAct");
                    String recChannel = selectSingleNodeByRoot(root,
                            "/ATS/OUT/RecChannel");
                    String abstracts = selectSingleNodeByRoot(root,
                            "/ATS/OUT/Abstract");
                    String payMadeDate = selectSingleNodeByRoot(root,
                            "/ATS/OUT/PayMadeDate");
                    SimpleDateFormat sf = new SimpleDateFormat(
                            "yyyy-MM-dd HH:mm:ss");
                    Date parse = sf.parse(payMadeDate);
                    facadeNewPayment.setRdSeq(rdSeq);
                    facadeNewPayment.setCancelState(cancelState);
                    facadeNewPayment.setTransState(transState);
                    facadeNewPayment.setMerid(corpAct);
                    facadeNewPayment.setPayDate(parse);
                    facadeNewPayment.setAbstracts(abstracts);
                    facadeNewPayment.setPayType(recChannel);
                    facadeNewPayment.setFeedBackDate(new Date());
                    facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);
                } else {// 如果查询返回是2-已收款以外状态继续调用支付接口
                    facadeNewPayment.setTransState("1");
                    facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);
                }
            } else {
                //如果交易返回码是notexists，需换一个订单号请求
                if ("notexists".equals(RtnCode)) {
                    facadeNewPayment.setRdSeq(generatePaySerialNumber(
                            facadeNewPayment.getPayId()));
                }
                facadeNewPayment.setTransState("1");
                facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);
            }
        } catch (Exception e) {
            facadeNewPayment.setTransState("1");// 如果查询返回是未支付状态或支付失败状态,都要把支付表状态置为1未支付状态
            facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);
            logger.error("收款状态查询超时或失败:" + e);
        }
        return facadeNewPayment;
    }

    public String selectSingleNodeByRoot(Element root, String path) {
        Node node = root.selectSingleNode(path);
        if (node == null) {
            return "";
        } else {
            return node.getText();
        }
    }

    /**
     * 出库缴费完成更新出库表状态
     * 
     * @param payId
     * @param statusBef
     * @param statusAft
     * @throws Exception
     */
    @Override
    public void updatCommamtInfo(String payId, String statusBef,
            String statusAft) throws Exception {
        HashMap<String, Object> param = new HashMap<String, Object>();
        param.put("commamtId", payId);
        param.put("statusBef", statusBef);
        param.put("statusAft", statusAft);
        param.put("isNewpay", "0");
        // 更新出库费用表的状态和预收单号
        commamtFeeDao.updatCommamtInfo(param);
    }

    /**
     * 出库缴费完成更新卡单表状态
     * 
     * @param payId
     * @param statusBef
     * @param statusAft
     * @throws Exception
     */
    @Override
    public void updateStatusByCommamtId(String payId, String statusBef,
            String statusAft) throws Exception {
        HashMap<String, Object> param = new HashMap<String, Object>();
        param.put("commamtId", payId);
        param.put("statusBef", statusBef);
        param.put("statusAft", statusAft);
        param.put("payMrk", "Y");
        outboundCardApplyDao.updateStatusByCommamtId(param);
    }

    /**
     * 根据出库id生成支付流水号
     * 
     * @param commantId
     * @return
     */
    private String generatePaySerialNumber(String commantId) throws Exception {
        String code = facadeNewPaymentDao.findFacadeNewPayByPayId(commantId);
        if (code == null || code.equals("")) {
            code = "0001";
        }
        String format = String.format("%02d",(int)(Math.random()*100));
        return "jhcard"+System.nanoTime()+format+code;
    }

    /**
     * 根据出库ID查找出库人数字工号
     * 
     * @param payId
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> getEmployeeNoByCommamtId(String payId)
            throws Exception {
        return (Map<String, String>) outboundCardApplyDao
                .getEmployeeNoByCommamtId(payId);
    }

    /**
     * 更新收款表
     * 
     * @param facadeNewPayment
     * @throws Exception
     */
    @Override
    public boolean updateFacadeNewPay(FacadeNewPayment facadeNewPayment)
            throws Exception {
        return facadeNewPaymentDao.updateFacadeNewPay(facadeNewPayment);

    }

}
